package org.jeeasy.system.modules.user.controller;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeeasy.common.core.annotation.dict.DictTranslation;
import org.jeeasy.common.core.base.SimpleCurdController;
import org.jeeasy.common.core.config.valid.group.CreateGroup;
import org.jeeasy.common.core.domain.IAuthUser;
import org.jeeasy.common.core.domain.vo.R;
import org.jeeasy.common.core.enums.DelFlagEnum;
import org.jeeasy.common.core.exception.JeeasyException;
import org.jeeasy.common.core.handler.userpwd.UserPasswordHandler;
import org.jeeasy.common.core.tools.QueryGenerator;
import org.jeeasy.common.core.tools.Tools;
import org.jeeasy.system.modules.premission.domain.vo.MenuVo;
import org.jeeasy.system.modules.premission.service.SysPermissionService;
import org.jeeasy.system.modules.user.domain.SysUser;
import org.jeeasy.system.modules.user.domain.model.ChangePasswordByOldPasswordModel;
import org.jeeasy.system.modules.user.domain.model.SysUserQueryPageModel;
import org.jeeasy.system.modules.user.domain.model.UserInfoModel;
import org.jeeasy.system.modules.user.domain.vo.SysUserVo;
import org.jeeasy.system.modules.user.service.SysUserService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author AlpsDDJ
 * @date 2020/11/9
 */
@Slf4j
@Validated
@RestController
@Tag(name = "系统用户")
@RequestMapping("/sys/user")
@RequiredArgsConstructor
public class SysUserController extends SimpleCurdController<SysUserService, SysUser> {
    private final SysPermissionService permissionService;

    @GetMapping
    @DictTranslation
    @Operation(summary = "用户列表", description = "用户列表")
    public R<IPage<SysUserVo>> list(SysUserQueryPageModel queryPageModel) {
        queryPageModel.defaultSort("userNo");
        QueryWrapper<SysUser> wrapper = QueryGenerator.ofWrapper(SysUser.class, queryPageModel);
        //if (queryPageModel.noSort()) {
        //    wrapper.lambda().orderByAsc(SysUser::getUserNo);
        //}
        String[] deptId = queryPageModel.getDepts();
        String[] roleId = queryPageModel.getRoles();
        if (Tools.isNotEmpty(deptId)) {
            List<String> deptIds = CollectionUtil.newArrayList(deptId);
            if (deptIds.size() == 1) {
                wrapper.eq("dept_id", deptIds.get(0));
            } else if (deptIds.size() > 1) {
                wrapper.in("dept_id", deptIds);
            }
        }
        if (Tools.isNotEmpty(roleId)) {
            List<String> roleIds = CollectionUtil.newArrayList(roleId);
            if (roleIds.size() == 1) {
                wrapper.eq("role_id", roleIds.get(0));
            } else if (roleIds.size() > 1) {
                wrapper.in("role_id", roleIds);
            }
        }
        wrapper.lambda().eq(SysUser::getDelFlag, DelFlagEnum.NO.getValue());
        IPage<SysUserVo> sysUserVoList = service.querySysUserVoPage(wrapper, queryPageModel);
        return R.ok(sysUserVoList);
    }

    @GetMapping("/{id}")
    @DictTranslation
    @Operation(summary = "根据ID查找用户", description = "根据ID查找用户")
    public R<SysUserVo> info(@NotBlank(message = "id不能为空") @PathVariable("id") String id) {
        return R.ok(super.getById(id).transfer(SysUserVo.class));
    }

    @PostMapping
    @Operation(summary = "添加用户", description = "添加用户")
    public R<Void> add(@Validated({CreateGroup.class}) @RequestBody UserInfoModel model) {
        service.insertUserWithUserInfoModel(model);
        return R.ok();
    }

    @PutMapping
    @Operation(summary = "修改用户", description = "修改用户")
    public R<Void> edit(@Validated @RequestBody UserInfoModel model) {
        //log.info("BindingResult:{}", bindingResult.hasErrors());
        service.updateUserWithUserInfoModel(model);
        return R.ok();
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "根据ID删除用户", description = "根据ID删除用户")
    public R<Void> remove(@PathVariable("id") String id) {
        super.deleteById(id);
        return R.ok();
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除用户", description = "批量删除用户")
    public R<Void> batchRemove(@RequestParam(name = "ids") String ids) {
        super.batchDelete(ids);
        return R.ok();
    }

    /**
     * 通过旧密码验证修改新密码
     *
     * @param model
     * @return
     */
    @PutMapping("/changePasswordByOldPassword")
    @Operation(summary = "修改用户密码", description = "通过旧密码验证修改新密码")
    public R<Void> changePasswordByOldPassword(@Valid @RequestBody ChangePasswordByOldPasswordModel model) {
        SysUser sysUser = this.service.getById(model.getId());
        UserPasswordHandler<SysUser> userPasswordHandler = UserPasswordHandler.create(sysUser);
        if (userPasswordHandler.checkPassword(model.getOldPassword())) {
            userPasswordHandler.changePassword(model.getNewPassword());
            this.service.updateById(sysUser);
            return R.ok();
        } else {
            throw new JeeasyException("原密码错误");
        }
    }

    /**
     * 重置用户密码为初始密码 [123456]
     *
     * @param id
     * @return {@link R<Void>}
     * @author AlpsDDJ
     * @date 2020/11/21 21:50
     */
    @PutMapping("/resetPassword")
    @Operation(summary = "重置用户密码", description = "重置用户密码为初始密码")
    public R<Void> resetPassword(@RequestBody String id) {
        SysUser sysUser = this.service.getById(id);
        this.update(UserPasswordHandler.create(sysUser).initSaltAndPassword());
        return R.ok();
    }


    @GetMapping("/menus")
    @DictTranslation
    @Operation(summary = "当前登录用户菜单列表", description = "当前登录用户菜单列表")
    public R<List<MenuVo>> menus() {
        SaSession session = StpUtil.getSession();
        IAuthUser model = (IAuthUser) session.get(IAuthUser.SESSION_KEY);
        log.debug(model.toString());
        String username = model.username();
        List<MenuVo> sysPermissions = null;
        if (IAuthUser.SUPER_USERNAME.equals(username)) {
            sysPermissions = permissionService.querySuperUserMenu();
        } else {
            String currentAuthUserId = StpUtil.getLoginId().toString();
            sysPermissions = permissionService.queryMenuByUserId(currentAuthUserId);
        }
        return R.ok(sysPermissions);
    }

}
